{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在MATLAB里，`*` 代表矩阵乘法。但是在numpy里，`*`表示element-wise prodct。要想做到矩阵乘法，要用多函数dot:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x = np.array([[1., 2., 3.], [4., 5., 6.]])\n",
    "\n",
    "y = np.array([[6., 23.], [-1, 7], [8, 9]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.,  2.,  3.],\n",
       "       [ 4.,  5.,  6.]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[  6.,  23.],\n",
       "       [ -1.,   7.],\n",
       "       [  8.,   9.]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[  28.,   64.],\n",
       "       [  67.,  181.]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.dot(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`x.dot(y)`等同于`np.dot(x, y)`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[  28.,   64.],\n",
       "       [  67.,  181.]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(x, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个二维数组和一个一维数组的矩阵乘法，得到一个一维数组："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  6.,  15.])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(x, np.ones(3))  \n",
    "# 这里应该是用狂了boradcasting，x中的每一行与[1, 1, 1]点对点乘积后求和"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`@`作为一个中缀计算符（鬼知道这是什么东西），也能实现矩阵乘法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  6.,  15.])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x @ np.ones(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`np.linalg`能用来做矩阵分解，以及比如转置和求秩之类的事情："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from numpy.linalg import inv, qr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.0761557 , -0.34138565, -0.56325926,  1.7854    ,  1.23440008],\n",
       "       [ 1.46787829,  1.73130465,  1.03519282,  1.11137573, -0.05928319],\n",
       "       [-0.95508009, -1.35350494, -1.43415583, -0.28499706,  0.32739284],\n",
       "       [ 0.83307271,  1.89349058,  0.94116452,  0.32347353,  0.22236912],\n",
       "       [-1.20661273,  0.4531822 ,  0.47635565, -1.69312137, -0.34497803]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# X = np.round(np.random.randn(5, 5), 3) # 这里我们用np.round控制小数点后的位数，看起来更舒服一些\n",
    "X = np.random.randn(5, 5)\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 5.22,  4.84,  3.06,  4.35,  0.3 ],\n",
       "       [ 4.84,  8.74,  5.92,  1.55, -0.7 ],\n",
       "       [ 3.06,  5.92,  4.56,  0.05, -1.18],\n",
       "       [ 4.35,  1.55,  0.05,  7.48,  2.7 ],\n",
       "       [ 0.3 , -0.7 , -1.18,  2.7 ,  1.8 ]])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mat = X.T.dot(X)\n",
    "np.round(mat, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 12.14,  -6.15,   3.85, -11.22,  14.95],\n",
       "       [ -6.15,   4.85,  -4.47,   5.7 ,  -8.57],\n",
       "       [  3.85,  -4.47,   5.23,  -3.78,   6.71],\n",
       "       [-11.22,   5.7 ,  -3.78,  10.77, -14.55],\n",
       "       [ 14.95,  -8.57,   6.71, -14.55,  20.95]])"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(inv(mat), 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.,  0.,  0.,  0., -0.],\n",
       "       [-0.,  1.,  0., -0., -0.],\n",
       "       [ 0., -0.,  1., -0.,  0.],\n",
       "       [-0.,  0.,  0.,  1.,  0.],\n",
       "       [ 0.,  0., -0.,  0.,  1.]])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(mat.dot(inv(mat)), 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "q, r = qr(mat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ -8.89, -10.37,  -6.57,  -7.16,  -0.77],\n",
       "       [  0.  ,  -5.5 ,  -4.79,   5.41,   3.04],\n",
       "       [  0.  ,   0.  ,  -0.71,   1.85,   1.54],\n",
       "       [  0.  ,   0.  ,   0.  ,  -0.75,  -0.53],\n",
       "       [  0.  ,   0.  ,   0.  ,   0.  ,   0.03]])"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(r, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`X.T.dot(X)`计算的是X和X的转置的矩阵乘法。\n",
    "\n",
    "一些常用的numpy.linalg函数：\n",
    "\n",
    "![](http://oydgk2hgw.bkt.clouddn.com/pydata-book/3jol9.png)\n",
    "\n",
    "![](http://oydgk2hgw.bkt.clouddn.com/pydata-book/5nfep.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [py35]",
   "language": "python",
   "name": "Python [py35]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
